package com.cwt.common.aspect.datasource;

import com.cwt.common.datasource.DynamicDataSource;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * 数据源切面，切换数据眼
 */
@Aspect
@Component
@Order(1)
public class DynamicDataSourceAspect {

    @Pointcut("@annotation(com.cwt.common.aspect.datasource.DataSource)"
            + "|| @within(com.cwt.common.aspect.datasource.DataSource)")
    public void dsPointCut() {

    }

    @Around("dsPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        DataSource dataSource = getDataSource(point);

        // 切换数据源
        if (Objects.nonNull(dataSource)) {
            DynamicDataSource.setDataSourceType(dataSource.value().name());
        }
        try {
            // 执行方法
            return point.proceed();
        } finally {
            // 方法执行之后，清空数据源
            DynamicDataSource.clearDataSourceType();
        }
    }

    public DataSource getDataSource(ProceedingJoinPoint point) {
        MethodSignature signature = (MethodSignature) point.getSignature();
        DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class);
        if (Objects.nonNull(dataSource)) {
            return dataSource;
        }
        return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class);
    }

}
